home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # PrGeneralPlay.c
- #
- # PrGeneralPlay is an example application that demonstrates the use
- # of PrGeneral's opcodes: GetRslData, SetRsl, GetRotn, DraftBits, and
- # NoDraftBits. For complete details about the functionality of this
- # application, see the header at the top of the PrGeneralPlayPrint.c file.
- #
- # ------------------------------------------------------------------------------
- #
- # Versions: 1.00 June 1, 1990
- #
- # Components: PrGeneralPlay.c June 1, 1990
- # PrGeneralPlayPrint.c June 1, 1990
- # PrGeneralPlay.h June 1, 1990
- # PrGeneralPlay.r June 1, 1990
- #
- #
- # Apple Macintosh Developer Technical Support
- # Copyright © 1990 Apple Computer, Inc.
- # All rights reserved.
- #
- ------------------------------------------------------------------------------*/
-
- #include <Values.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <DiskInit.h>
- #include <Packages.h>
- #include <Traps.h>
- #include <Printing.h>
- #include <PrGeneralPlay.h> /* bring in all of the #defines for PrGeneralPlay */
-
- #define QD32Trap 0xAB03
- #define Unimplemented 0xA89F
-
-
- SysEnvRec gMac; /* set up by Initialize */
- Boolean gHasWaitNextEvent; /* set up by Initialize */
-
- THPrint gPrRecHdl;
-
- Boolean gHighResolutionON, /** These globals are set up by Initialize **/
- gUseDraftBits,
- gCheckForLandscape,
- gDraftBitsHasBeenSet;
- gPrGeneralLives,
- gLandscapeOpImpl,
- gDraftBitsOpImpl,
- gSetRslOpImpl;
-
- short gOriginalDriverVers;
-
-
- /* Here are declarations for all of the C routines. In MPW 3.0 we can use
- actual prototypes for parameter type checking. */
- void EventLoop( void );
- void DoEvent( EventRecord *event );
- void GetGlobalMouse( Point *mouse );
- void AdjustMenus( void );
- void DoMenuCommand( long menuResult );
- void Terminate( void );
- void Initialize( void );
- void ForceEnvirons( void );
- Boolean IsDAWindow( WindowPtr window );
- Boolean TrapAvailable( short tNumber, TrapType tType );
- void AlertUser( void );
- void QD32BitAlertUser ( void );
-
- extern Boolean testForPrGeneral ( void );
- extern void noPrGeneralAlert ( void );
-
-
- /* Define HiWrd and LoWrd macros for efficiency. */
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
-
- /* Define TopLeft and BotRight macros for convenience. Notice the implicit
- dependency on the ordering of fields within a Rect */
- #define TopLeft(aRect) (* (Point *) &(aRect).top)
- #define BotRight(aRect) (* (Point *) &(aRect).bottom)
-
-
- extern void _DataInit();
-
- /* This routine is part of the MPW runtime library. This external
- reference to it is done so that we can unload its segment, %A5Init. */
-
-
- #pragma segment Main
- main()
- {
- UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
-
- /* 1.01 - call to ForceEnvirons removed */
-
- /* If you have stack requirements that differ from the default,
- then you could use SetApplLimit to increase StackSpace at
- this point, before calling MaxApplZone. */
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- Initialize(); /* initialize the program */
- UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */
-
- EventLoop(); /* call the main event loop */
- }
-
-
- /* Get events forever, and handle them by calling DoEvent.
- Get the events by calling WaitNextEvent, if it's available, otherwise
- by calling GetNextEvent. */
-
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
- do {
- /* use WNE if it is available */
- if ( gHasWaitNextEvent )
- gotEvent = WaitNextEvent(everyEvent, &event, 30, cursorRgn);
- else {
- SystemTask();
- gotEvent = GetNextEvent(everyEvent, &event);
- }
-
- if ( gotEvent ) DoEvent(&event);
-
- } while ( true ); /* loop forever; we quit via ExitToShell */
- } /*EventLoop*/
-
-
- /* Do the right thing for an event. Determine what kind of event it is, and call
- the appropriate routines. */
-
- #pragma segment Main
- void DoEvent(event)
- EventRecord *event;
- {
- short part, err;
- WindowPtr window;
- Boolean hit;
- char key;
- Point aPoint;
-
- switch ( event->what ) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch ( part ) {
- case inMenuBar: /* process a mouse menu command (if any) */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(event, window);
- break;
- case inContent:
- break;
- case inDrag: /* pass screenBits.bounds to get all gDevices */
- DragWindow(window, event->where, &qd.screenBits.bounds);
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- hit = TrackBox(window, event->where, part);
- if ( hit ) {
- SetPort(window); /* the window must be the current port... */
- EraseRect(&window->portRect); /* because of a bug in ZoomWindow */
- ZoomWindow(window, part, true); /* note that we invalidate and erase... */
- InvalRect(&window->portRect); /* to make things look better on-screen */
- }
- break;
- }
- break;
- case keyDown:
- case autoKey: /* check for menukey equivalents */
- key = event->message & charCodeMask;
- if ( event->modifiers & cmdKey ) /* Command key down */
- if ( event->what == keyDown ) {
- AdjustMenus(); /* enable/disable/check menu items properly */
- DoMenuCommand(MenuKey(key));
- }
- break;
- case activateEvt:
- break;
- case updateEvt:
- break;
- /* 1.01 - It is not a bad idea to at least call DIBadMount in response
- to a diskEvt, so that the user can format a floppy. */
- case diskEvt:
- if ( HiWord(event->message) != noErr ) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event->message);
- }
- break;
- case kOSEvent:
- break;
- }
- } /*DoEvent*/
-
-
- /* Get the global coordinates of the mouse. When you call OSEventAvail
- it will return either a pending event or a null event. In either case,
- the where field of the event record will contain the current position
- of the mouse in global coordinates and the modifiers field will reflect
- the current state of the modifiers. Another way to get the global
- coordinates is to call GetMouse and LocalToGlobal, but that requires
- being sure that thePort is set to a valid port. */
-
- #pragma segment Main
- void GetGlobalMouse(mouse)
- Point *mouse;
- {
- EventRecord event;
-
- OSEventAvail(kNoEvents, &event); /* we aren't interested in any events */
- *mouse = event.where; /* just the mouse position */
- } /*GetGlobalMouse*/
-
-
- /* Enable and disable menus based on the current state.
- The user can only select enabled menu items. We set up all the menu items
- before calling MenuSelect or MenuKey, since these are the only times that
- a menu item can be selected. Note that MenuSelect is also the only time
- the user will see menu items. This approach to deciding what enable/
- disable state a menu item has the advantage of concentrating all
- the decision-making in one routine, as opposed to being spread throughout
- the application. Other application designs may take a different approach
- that is just as valid. */
-
- #pragma segment Main
- void AdjustMenus()
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMHandle(mFile);
-
- if ( IsDAWindow(window) ) { /* we can allow desk accessories to be closed from the menu */
- DisableItem(menu, iNew);
- DisableItem(menu, iOpen);
- DisableItem(menu, iSave);
- DisableItem(menu, iSaveAs);
- DisableItem(menu, iRevert);
- DisableItem(menu, iPageSetup);
- DisableItem(menu, iPrint);
- EnableItem(menu, iClose);
- }
- else {
- EnableItem(menu, iPageSetup);
- EnableItem(menu, iPrint);
- }
-
- menu = GetMHandle(mEdit);
- if ( IsDAWindow(window) ) { /* a desk accessory might need the edit menu… */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- } else { /* …but we don’t use it */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
-
- menu = GetMHandle(mPrGeneral);
- if ( gPrGeneralLives)
- {
- // If the particular opcode is supported by the current printer driver,
- // enable the menu item, otherwise dis-able it....
-
- if (gLandscapeOpImpl)
- EnableItem(menu, iCheckForLandscape);
- else
- {
- CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
- DisableItem(menu, iCheckForLandscape);
- }
-
- if (gSetRslOpImpl)
- EnableItem(menu, iTurnHighResOFF);
- else
- {
- CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
- DisableItem(menu, iTurnHighResOFF);
- }
-
- if (gDraftBitsOpImpl)
- EnableItem(menu, iUseDraftBits);
- else
- {
- CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
- DisableItem(menu, iUseDraftBits);
- }
- }
- else {
- CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
- DisableItem(menu, iTurnHighResOFF);
-
- CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
- DisableItem(menu, iUseDraftBits);
-
- CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
- DisableItem(menu, iCheckForLandscape);
- }
-
- } /*AdjustMenus*/
-
-
- /* This is called when an item is chosen from the menu bar (after calling
- MenuSelect or MenuKey). It performs the right operation for each command.
- It is good to have both the result of MenuSelect and MenuKey go to
- one routine like this to keep everything organized. */
-
- #pragma segment Main
- void DoMenuCommand(menuResult)
- long menuResult;
- {
- short menuID; /* the resource ID of the selected menu */
- short menuItem; /* the item number of the selected menu */
- short itemHit,
- printErr = 0;
- Str255 daName;
- short daRefNum;
- Boolean handledByDA;
-
- menuID = HiWord(menuResult); /* use macros for efficiency to... */
- menuItem = LoWord(menuResult); /* get menu item number and menu number */
- switch ( menuID ) {
- case mApple:
- switch ( menuItem ) {
- case iAbout: /* bring up alert for About */
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: /* all non-About items in this menu are DAs */
- /* type Str255 is an array in MPW 3 */
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch ( menuItem ) {
- case iNew:
- break;
- case iOpen:
- break;
- case iSave:
- break;
- case iClose:
- break;
- case iPageSetup:
- PresentStyleDialog();
- break;
- case iPrint:
- PrintThis();
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- case mEdit: /* call SystemEdit for DA editing & MultiFinder */
- handledByDA = SystemEdit(menuItem-1); /* since we don’t do any Editing */
- break;
- case mPrGeneral:
- switch ( menuItem ) {
- case iTurnHighResOFF:
- {
- PrOpen ();
- if (PrError () == noErr)
- {
- if (!gHighResolutionON)
- {
- gHighResolutionON = true;
- CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, true);
-
- doSetRsl();
- }
- else
- {
- gHighResolutionON = false;
- CheckItem(GetMHandle(mPrGeneral), iTurnHighResOFF, false);
-
- resetSetRsl();
- }
- }
- else printErr = PrError ();
-
- PrClose ();
-
- if (printErr != noErr) AlertUser ();
- }
- break;
- case iUseDraftBits:
- {
- PrOpen ();
- if (PrError () == noErr)
- {
- if (!gUseDraftBits)
- {
- gUseDraftBits = true;
- CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, true);
-
- doDraftBits ();
- }
- else
- {
- gUseDraftBits = false;
- CheckItem(GetMHandle(mPrGeneral), iUseDraftBits, false);
-
- doNODraftBits ();
- }
-
- }
- else printErr = PrError ();
-
- PrClose ();
-
- if (printErr != noErr) AlertUser ();
- }
- break;
- case iCheckForLandscape:
- {
- if (!gCheckForLandscape)
- {
- gCheckForLandscape = true;
- CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, true);
- }
- else
- {
- gCheckForLandscape = false;
- CheckItem(GetMHandle(mPrGeneral), iCheckForLandscape, false);
- }
- }
- break;
- }
- break;
- }
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /*DoMenuCommand*/
-
-
- /* Clean up the application and exit. We close all of the windows so that
- they can update their documents, if any. */
-
- #pragma segment Main
- void Terminate()
- {
- if (gPrRecHdl != nil)
- DisposHandle ((Handle) gPrRecHdl); // Dispose of the print record
-
- ExitToShell();
-
- } /*Terminate*/
-
-
-
- /* 1.01 - The code that used to be part of ForceEnvirons has been moved into
- this module. If an error is detected, instead of merely doing an ExitToShell,
- which leaves the user without much to go on, we call AlertUser, which puts
- up a simple alert that just says an error occurred and then calls ExitToShell.
- Since there is no other cleanup needed at this point if an error is detected,
- this form of error- handling is acceptable. If more sophisticated error recovery
- is needed, an exception mechanism, such as is provided by Signals, can be used. */
-
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- long total, contig;
- EventRecord event;
- short count,
- myPrintErr;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- MaxApplZone(); MoreMasters(); MoreMasters;
-
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
-
-
- if (gMac.machineType < 0) AlertUser();
-
-
- // We need the GWorld stuff (i.e. 32-bit QD) when printing in "draft" mode...
- if (gMac.hasColorQD)
- {
- // Check to make sure the 32-Bit QuickDraw trap exists
- if (NGetTrapAddress(QD32Trap, ToolTrap) == GetTrapAddress(Unimplemented))
- QD32BitAlertUser();
- }
- else QD32BitAlertUser();
-
-
- gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
-
- if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) AlertUser();
-
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace) AlertUser();
-
-
- menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */
- if ( menuBar == nil ) AlertUser();
- SetMenuBar(menuBar); /* install menus */
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
- DrawMenuBar();
-
- /**
- Initialize these booleans to enable the print loop (in PrGeneralPlayPrint.c)
- to determine which PrGeneral opcodes should be used at print time.
- **/
- gHighResolutionON = false;
- gUseDraftBits = false;
- gCheckForLandscape = false;
- gDraftBitsHasBeenSet = false;
-
- /**
- We will assume at this point that all of PrGeneral's opcodes are supported.
- When we make a call for a particular opcode, we will check to make sure that
- the opcode is supported. If it is NOT, the appropraite flag will be set to false
- and that opcode will not be called until the printer driver is changed.
- **/
- gLandscapeOpImpl = true;
- gDraftBitsOpImpl = true;
- gSetRslOpImpl = true;
-
- /**
- Create & initialize the print record....
- **/
- myPrintErr = 0;
- gPrRecHdl = (THPrint) NewHandle(sizeof(TPrint));
-
-
- if (MemError() == noErr && gPrRecHdl != nil)
- {
- PrOpen();
- if (PrError() == noErr)
- {
- PrintDefault (gPrRecHdl);
-
- // We need to save the version number of the current printer driver. This will enable
- // us to compare the version of the printer driver when the user chooses a different
- // printer driver via the Chooser. This important because some earlier versions of
- // Apple's printers drivers did not support PrGeneral. Which is the case for the
- // ImageWriter v2.5 and LaserWriter v4.0 and earlier.
-
- gOriginalDriverVers = PrDrvrVers ();
-
- if (PrError () == noErr)
- gPrGeneralLives = testForPrGeneral (); // Check to see if the current printer driver
- else myPrintErr = PrError (); // supports PrGeneral and set the global flag...
- }
- else myPrintErr = PrError (); // Grab the error before we close the Print Manager
- PrClose();
-
- if (myPrintErr != 0)
- AlertUser ();
- }
- else AlertUser ();
-
- } /*Initialize*/
-
-
- /* Check to see if a window belongs to a desk accessory. */
-
- #pragma segment Main
- Boolean IsDAWindow(window)
- WindowPtr window;
- {
- if ( window == nil )
- return false;
- else /* DA windows have negative windowKinds */
- return ((WindowPeek) window)->windowKind < 0;
- } /*IsDAWindow*/
-
-
- /* Check to see if a given trap is implemented. This is only used by the
- Initialize routine in this program, so we put it in the Initialize segment.
- The recommended approach to see if a trap is implemented is to see if
- the address of the trap routine is the same as the address of the
- Unimplemented trap. */
- /* 1.02 - Needs to be called after call to SysEnvirons so that it can check
- if a ToolTrap is out of range of a pre-MacII ROM. */
-
- #pragma segment Initialize
- Boolean TrapAvailable(tNumber,tType)
- short tNumber;
- TrapType tType;
- {
- if ( ( tType == ToolTrap ) &&
- ( gMac.machineType > envMachUnknown ) &&
- ( gMac.machineType < envMacII ) ) { /* it's a 512KE, Plus, or SE */
- tNumber = tNumber & 0x03FF;
- if ( tNumber > 0x01FF ) /* which means the tool traps */
- tNumber = _Unimplemented; /* only go to 0x01FF */
- }
- return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
- } /*TrapAvailable*/
-
-
-
- /* Display an alert that tells the user an error occurred, then exit the program.
- This routine is used as an ultimate bail-out for serious errors that prohibit
- the continuation of the application. Errors that do not require the termination
- of the application should be handled in a different manner. Error checking and
- reporting has a place even in the simplest application. The error number is used
- to index an 'STR#' resource so that a relevant message can be displayed. */
-
- #pragma segment Main
- void AlertUser()
- {
- short itemHit;
-
- SetCursor(&qd.arrow);
- itemHit = Alert(rUserAlert, nil);
- ExitToShell();
- } /* AlertUser */
-
-
-
- // Display an alert to tell the user that 32-bit QuickDraw is required to
- // run PrGeneral Play...
-
- #pragma segment Main
- void QD32BitAlertUser()
- {
- short itemHit;
-
- SetCursor(&qd.arrow);
-
- itemHit = Alert(r32BitQDAlert, nil);
- ExitToShell();
- } // end of QD32BitAlertUser
-
-
-
-